home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / unixlib.lha / unix / src / stat.c < prev    next >
C/C++ Source or Header  |  1996-11-10  |  3KB  |  108 lines

  1. #include "amiga.h"
  2. #include "dir_data.h"
  3. #include <utility/tagitem.h>
  4. #include <sys/stat.h>
  5. #include <string.h>
  6.  
  7. static int attach(char *dest, int dlen, char *dirname, char *name)
  8. {
  9.     char *dirnamep = dirname;
  10.  
  11.     while (*dirnamep && --dlen > 0)
  12.     *dest++ = *dirnamep++;
  13.     /* Add '/' if `dirname' doesn't already end with it. */
  14.     if (dirnamep > dirname && dirnamep[-1] != '/' && dirnamep[-1] != ':' && --dlen > 0)
  15.     *dest++ = '/';
  16.  
  17.     while (*name && --dlen > 0)
  18.     *dest++ = *name++;
  19.     *dest = 0;
  20.  
  21.     return dlen > 0;
  22. }
  23.  
  24. static struct FileInfoBlock fakefib;
  25. static char last_name[256];
  26.  
  27. int stat(const char *name, struct stat *sbuf)
  28. {
  29.     struct FileInfoBlock *fib = 0;
  30.     BPTR lock = 0;
  31.     int ret;
  32.  
  33.     __chkabort();
  34.     /* See if we want information on the last file returned from readdir */
  35.     if (last_info && last_info->cdir == _get_cd() &&
  36.     attach(last_name, 255, last_info->dirname, last_entry->entry.d_name) &&
  37.     strcmp(last_name, name) == 0) {
  38.     /* We do ! Fake a fib */
  39.  
  40.     fakefib.fib_DiskKey = last_entry->entry.d_ino;
  41.     fakefib.fib_NumBlocks = last_entry->numblocks;
  42.     fakefib.fib_Size = last_entry->size;
  43.     fakefib.fib_Date = last_entry->date;
  44.     fakefib.fib_DirEntryType = last_entry->type;
  45.     fakefib.fib_Protection = last_entry->protection;
  46.  
  47.     _fibstat(&fakefib, 0, sbuf, last_entry->handler);
  48.     ret = 0;
  49.     } else if ((fib = AllocDosObjectTags(DOS_FIB, TAG_END)) &&
  50.            (lock = Lock(name, SHARED_LOCK)) &&
  51.            Examine(lock, fib)) {
  52.     BPTR parent = ParentDir(lock);
  53.     int isroot = !parent;
  54.     long handler = (long)((struct FileLock *)((long)lock << 2))->fl_Task;
  55.  
  56.     if (parent)
  57.         UnLock(parent);
  58.     _fibstat(fib, isroot, sbuf, handler);
  59.     ret = 0;
  60.     } else if (fib && !lock) {
  61.     char *buf = strdup(name);
  62.     char *p;
  63.     char sc = 0;
  64.  
  65.     for (p = buf + strlen(buf); p >= buf && *p != ':' && *p != '/'; --p);
  66.  
  67.     if (p < buf || *p == ':') {
  68.         ++p;
  69.         sc = *p;
  70.     }
  71.     *p = 0;
  72.     lock = Lock(buf, SHARED_LOCK);
  73.     if (sc)
  74.         *p = sc;
  75.     else
  76.         ++p;
  77.  
  78.     ret = -1;
  79.     if (lock == NULL) {
  80.         errno = convert_oserr(IoErr());
  81.     } else {
  82.         long handler = (long)((struct FileLock *)((long)lock << 2))->fl_Task;
  83.         if (Examine(lock, fib)) {
  84.         while (ExNext(lock, fib)) {
  85.             if (stricmp(p, fib->fib_FileName) == 0) {
  86.             _fibstat(fib, 0, sbuf, handler);
  87.             ret = 0;
  88.             break;
  89.             }
  90.         }
  91.         if (ret == -1)
  92.             errno = ENOENT;
  93.         } else {
  94.         errno = convert_oserr(IoErr());
  95.         }
  96.     }
  97.     free(buf);
  98.     } else {
  99.     ret = -1;
  100.     errno = convert_oserr(IoErr());
  101.     }
  102.     if (lock)
  103.     UnLock(lock);
  104.     if (fib)
  105.     FreeDosObject(DOS_FIB, fib);
  106.     return ret;
  107. }
  108.